package com.tzy.tzyrpccore.consumer;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tzy.tzyrpccore.api.RpcRequest;
import com.tzy.tzyrpccore.api.RpcResponse;
import okhttp3.*;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @author caituxinchu
 */
public class TzyRpcConsumerInvocationHandler implements InvocationHandler {

    private final String serviceName;

    public TzyRpcConsumerInvocationHandler(String serviceName) {
        this.serviceName = serviceName;
    }

    private final OkHttpClient client = new OkHttpClient.Builder()
            // 连接线城池 最大16个线程，存活时间60s
            .connectionPool(new ConnectionPool(16, 60, TimeUnit.SECONDS))
            // 连接时间
            .connectTimeout(1, TimeUnit.SECONDS)
            .readTimeout(1, TimeUnit.SECONDS)
            .writeTimeout(1, TimeUnit.SECONDS)
            .build();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        RpcRequest request = new RpcRequest();
        request.setServiceName(serviceName);
        request.setArgs(args);
        request.setMethodName(method.getName());
        //HTTP请求获取RpcResponse
        RpcResponse rpcResponse = getRpcResponse(request, method.getReturnType());
        if (rpcResponse.getStatus()) {
            return rpcResponse.getData();
        } else {
            return null;
        }
    }

    /**
     * 通过HTTP请求+json 获取RPCResponse
     *
     * @param request
     * @return
     */
    private RpcResponse getRpcResponse(RpcRequest request, Class<?> returnType) {
        try {
            Gson gson = new Gson();
            //将请求转成gson字符串
            String requestJsonData = gson.toJson(request);
            Response response = client.newCall(new Request.Builder()
                    .url("http://localhost:8080")
                    .post(RequestBody.create(requestJsonData, MediaType.get("application/json; charset=utf-8")))
                    .build()).execute();
            String responseData = response.body().string();
            //反序列化结果
            TypeToken<?> parameterized = TypeToken.getParameterized(RpcResponse.class, returnType);
            RpcResponse rpcResponse = gson.fromJson(responseData, parameterized.getType());
            return rpcResponse;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
